/**
 * 
 */
$$.Component = $$.Class({
	/**
	 * the constructor
	 */
	constructor: function(config){
		$$.put(this, {
			listeners: {}
			,plugins: []
		}, config);
		
		// instance plugins
		for(var i = 0; i < this.plugins.length; ++i){
			if($$.isFunction(this.plugins[i]))
				this.plugins[i] = new this.plugins[i](this);
			else
				this.plugins[i].init.call(this, this);
		}
		
		// instance listeners
		for(var i in this.listeners){
			var l = this.listeners[i];
			if($$.isFunction(l)){
				this['on' + i.ucfirst()](l);
			}else{
				this['on' + i.ucfirst()](l.fn, l.scope);		
			}
		}
	}
	/**
	 * register a/an event
	 * @param arguments
	 */
	,addEvents: function(/*args*/){
		var me = this;
		if(!me.$_events) me.$_events = {};
		
		for(var i = 0; i < arguments.length; ++i){
			if('undefined' != typeof me.$_events[arguments[i]]) continue;
			
			// create a blank array for contain event object
			me.$_events[arguments[i]] = [];
			
			// create the add listener function
			me['on' + arguments[i].ucfirst()] = (function(eName, fn, scope){
				me.$_events[eName].push({
					fn: fn
					,scope: scope	
				});
			}).appendArg([arguments[i]]);
			
			// create the remove listener function
			me['un' + arguments[i].ucfirst()] = (function(eName, fn, scope){
				var o = {
					fn: fn
					,scope: scope	
				};
				for(var i = 0; i <  me.$_events[eName].length; ++i){
					if(Object.equals(me.$_events[eName][i], o)) me.$_events[eName].splice(i, 1);
				}	
			}).appendArg([arguments[i]]);
		}
	}
	/**
	 * notity a event
	 */
	,fireEvent: function(/*name, args*/){
		var name = [].splice.call(arguments, 0, 1);
		
		if('undefiend' == this.$_events[name]){
			throw 'Event ' + name.toString() + ' not found!';
		}
		
		for(var i = 0; i < this.$_events[name].length; ++i){
			var e = this.$_events[name][i];
			
			// if one of callback return $$.VALUE_HALT
			// stop execute event and return $$.VALUE_HALT
			if($$.VALUE_HALT === e.fn.apply(e.scope, arguments)) return $$.VALUE_HALT;
		}
		return true;
	}
});